import {State} from '../src/state.js'
import * as C from '../src/const.js'
import assert from 'assert'

describe('state', function() {
  describe('state', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 0, 0)
      s.set_coord(C.T_BING1, 3, 0)
      s.set_coord(C.T_BING2, 2, 0)
      s.set_coord(C.T_BING3, 3, 1)
      s.set_coord(C.T_BING4, 2, 1)
      s.set_coord(C.T_MA, 0, 2)
      s.set_coord(C.T_HUANG, 1, 2)
      s.set_coord(C.T_ZHANG, 2, 2)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 2, 4)
      s.set_coord(C.T_FREE1, 0, 4)
      s.set_coord(C.T_FREE2, 1, 4)
      let coord = s.get_coord(C.T_CAO)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_BING1)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_BING2)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_MA)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_HUANG)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_ZHANG)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_ZHAO)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_GUAN)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 4)
      coord = s.get_coord(C.T_FREE1)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 4)
      coord = s.get_coord(C.T_FREE2)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 4)
    })
  })
})

describe('state1', function() {
  describe('state1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 0, 4)
      s.set_coord(C.T_BING2, 1, 3)
      s.set_coord(C.T_BING3, 2, 3)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 2)
      s.set_coord(C.T_ZHAO, 3, 0)
      s.set_coord(C.T_GUAN, 1, 2)
      s.set_coord(C.T_FREE1, 1, 4)
      s.set_coord(C.T_FREE2, 2, 4)
      let coord = s.get_coord(C.T_CAO)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_BING1)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 4)
      coord = s.get_coord(C.T_BING2)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 3)
      coord = s.get_coord(C.T_BING3)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 3)
      coord = s.get_coord(C.T_BING4)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 4)
      coord = s.get_coord(C.T_MA)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_HUANG)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_ZHANG)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_ZHAO)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 0)
      coord = s.get_coord(C.T_GUAN)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 2)
      coord = s.get_coord(C.T_FREE1)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 4)
      coord = s.get_coord(C.T_FREE2)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 4)
    })
  })
})

describe('deepcopy', function() {
  describe('deepcopy', function() {
    it('', function() {
      let s = new State()
      let buf = new Uint8Array(new ArrayBuffer(12))
      buf.fill(3, 0, 1)
      buf.fill(10, 1, 2)
      buf.fill(12, 2, 3)
      let a = s._deep_copy(buf)
      a.fill(20, 0, 1)
      console.log(a)
      console.log(buf)
    })
  })
})

  describe('move', function() {
    describe('move_right_1_2', function() {
      it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 3, 3)
      s.set_coord(C.T_BING2, 3, 2)
      s.set_coord(C.T_BING3, 3, 4)
      s.set_coord(C.T_BING4, 0, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 1, 2)
      s.set_coord(C.T_ZHAO, 3, 0)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 2, 2)
      s.set_coord(C.T_FREE2, 2, 3)
      let result = s._get1_2next(C.T_ZHANG)
      assert.equal(result.length, 1)
      let step = result[0].get_step()
      assert.equal(step.direction, C.RIGHT)
      assert.equal(step.index, C.T_ZHANG)
      let coord = result[0].get_coord(C.T_ZHANG)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 2)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 1)
      assert.equal(f1.y, 2)
      assert.equal(f2.x, 1)
      assert.equal(f2.y, 3)
    })
  })

  describe('move_left_1_2', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 3, 3)
      s.set_coord(C.T_BING2, 3, 2)
      s.set_coord(C.T_BING3, 3, 4)
      s.set_coord(C.T_BING4, 0, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 2, 2)
      s.set_coord(C.T_ZHAO, 3, 0)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 1, 2)
      s.set_coord(C.T_FREE2, 1, 3)
      let result = s._get1_2next(C.T_ZHANG)
      assert.equal(result.length, 1)
      let step = result[0].get_step()
      assert.equal(step.direction, C.LEFT)
      assert.equal(step.index, C.T_ZHANG)
      let coord = result[0].get_coord(C.T_ZHANG)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 2)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 2)
      assert.equal(f1.y, 2)
      assert.equal(f2.x, 2)
      assert.equal(f2.y, 3)
    })
  })

  describe('move_up_down_1_2', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 2, 2)
      s.set_coord(C.T_BING2, 2, 3)
      s.set_coord(C.T_BING3, 3, 4)
      s.set_coord(C.T_BING4, 0, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 1)
      s.set_coord(C.T_ZHAO, 1, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 3, 0)
      s.set_coord(C.T_FREE2, 3, 3)
      let result = s._get1_2next(C.T_ZHANG)
      assert.equal(result.length, 2)
      let step1 = result[0].get_step()
      assert.equal(step1.direction, C.UP)
      assert.equal(step1.index, C.T_ZHANG)
      let coord = result[0].get_coord(C.T_ZHANG)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 0)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 3)
      assert.equal(f1.y, 2)
      assert.equal(f2.x, 3)
      assert.equal(f2.y, 3)
      let step2 = result[1].get_step()
      assert.equal(step2.direction, C.DOWN)
      assert.equal(step2.index, C.T_ZHANG)
      coord = result[1].get_coord(C.T_ZHANG)
      assert.equal(coord.x, 3)
      assert.equal(coord.y, 2)
      f1 = result[1].get_coord(C.T_FREE1)
      f2 = result[1].get_coord(C.T_FREE2)
      assert.equal(f1.x, 3)
      assert.equal(f1.y, 0)
      assert.equal(f2.x, 3)
      assert.equal(f2.y, 1)
    })
  })

  describe('move_left_right_2_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 1, 2)
      s.set_coord(C.T_BING2, 2, 2)
      s.set_coord(C.T_BING3, 1, 3)
      s.set_coord(C.T_BING4, 2, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 0, 4)
      s.set_coord(C.T_FREE2, 3, 4)
      let result = s._get2_1next(C.T_GUAN)
      assert.equal(result.length, 2)
      let step = result[0].get_step()
      assert.equal(step.direction, C.RIGHT)
      assert.equal(step.index, C.T_GUAN)
      let coord = result[0].get_coord(C.T_GUAN)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 4)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 0)
      assert.equal(f1.y, 4)
      assert.equal(f2.x, 1)
      assert.equal(f2.y, 4)
      step = result[1].get_step()
      assert.equal(step.direction, C.LEFT)
      assert.equal(step.index, C.T_GUAN)
      coord = result[1].get_coord(C.T_GUAN)
      assert.equal(coord.x, 0)
      assert.equal(coord.y, 4)
      f1 = result[1].get_coord(C.T_FREE1)
      f2 = result[1].get_coord(C.T_FREE2)
      assert.equal(f1.x, 2)
      assert.equal(f1.y, 4)
      assert.equal(f2.x, 3)
      assert.equal(f2.y, 4)
    })
  })

  describe('move_up_2_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 1, 2)
      s.set_coord(C.T_BING2, 2, 2)
      s.set_coord(C.T_BING3, 0, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 1, 3)
      s.set_coord(C.T_FREE2, 2, 3)
      let result = s._get2_1next(C.T_GUAN)
      assert.equal(result.length, 1)
      let step = result[0].get_step()
      assert.equal(step.direction, C.UP)
      assert.equal(step.index, C.T_GUAN)
      let coord = result[0].get_coord(C.T_GUAN)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 3)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 1)
      assert.equal(f1.y, 4)
      assert.equal(f2.x, 2)
      assert.equal(f2.y, 4)
    })
  })

  describe('move_down_2_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 1, 2)
      s.set_coord(C.T_BING2, 2, 2)
      s.set_coord(C.T_BING3, 0, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 3)
      s.set_coord(C.T_FREE1, 1, 4)
      s.set_coord(C.T_FREE2, 2, 4)
      let result = s._get2_1next(C.T_GUAN)
      assert.equal(result.length, 1)
      let step = result[0].get_step()
      assert.equal(step.direction, C.DOWN)
      assert.equal(step.index, C.T_GUAN)
      let coord = result[0].get_coord(C.T_GUAN)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 4)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 1)
      assert.equal(f1.y, 3)
      assert.equal(f2.x, 2)
      assert.equal(f2.y, 3)
    })
  })

    describe('move_up_2_1_bug', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 0, 4)
      s.set_coord(C.T_BING2, 1, 4)
      s.set_coord(C.T_BING3, 2, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 2)
      s.set_coord(C.T_ZHAO, 3, 0)
      s.set_coord(C.T_GUAN, 1, 3)
      s.set_coord(C.T_FREE1, 1, 2)
      s.set_coord(C.T_FREE2, 2, 2)
      // let result = s._get2_1next(C.T_GUAN)
      // assert.equal(result.length, 1)
      // let step = result[0].get_step()
      // assert.equal(step.direction, C.UP)
      // assert.equal(step.index, C.T_GUAN)
      // let coord = result[0].get_coord(C.T_GUAN)
      // assert.equal(coord.x, 1)
      // assert.equal(coord.y, 2)
      // let f1 = result[0].get_coord(C.T_FREE1)
      // let f2 = result[0].get_coord(C.T_FREE2)
      // assert.equal(f1.x, 1)
      // assert.equal(f1.y, 3)
      // assert.equal(f2.x, 2)
      // assert.equal(f2.y, 3)
      console.log(s.buf.toString())
    })
  })

  describe('move_right_down1_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 1, 2)
      s.set_coord(C.T_BING2, 2, 3)
      s.set_coord(C.T_BING3, 0, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 2, 2)
      s.set_coord(C.T_FREE2, 1, 3)
      let result = s._get1_1next(C.T_BING1)
      assert.equal(result.length, 2)
      let step = result[0].get_step()
      assert.equal(step.direction, C.RIGHT)
      assert.equal(step.index, C.T_BING1)
      let coord = result[0].get_coord(C.T_BING1)
      assert.equal(coord.x, 2)
      assert.equal(coord.y, 2)
      let f1 = result[0].get_coord(C.T_FREE1)
      let f2 = result[0].get_coord(C.T_FREE2)
      assert.equal(f1.x, 1)
      assert.equal(f1.y, 2)
      assert.equal(f2.x, 1)
      assert.equal(f2.y, 3)
      step = result[1].get_step()
      assert.equal(step.direction, C.DOWN)
      assert.equal(step.index, C.T_BING1)
      coord = result[1].get_coord(C.T_BING1)
      assert.equal(coord.x, 1)
      assert.equal(coord.y, 3)
      f1 = result[1].get_coord(C.T_FREE1)
      f2 = result[1].get_coord(C.T_FREE2)
      assert.equal(f1.x, 2)
      assert.equal(f1.y, 2)
      assert.equal(f2.x, 1)
      assert.equal(f2.y, 2)
    })
  })

  describe('move_down_left_up_right1_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 0, 4)
      s.set_coord(C.T_BING2, 1, 4)
      s.set_coord(C.T_BING3, 2, 3)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 2)
      s.set_coord(C.T_FREE1, 1, 3)
      s.set_coord(C.T_FREE2, 2, 4)
      let result = s._get1_1next(C.T_BING3)
      assert.equal(result.length, 2)
      assert.equal(result[0].get_step().direction, C.DOWN)
      assert.equal(result[0].get_step().index, C.T_BING3)
      assert.equal(result[0].get_coord(C.T_BING3).x, 2)
      assert.equal(result[0].get_coord(C.T_BING3).y, 4)
      assert.equal(result[0].get_coord(C.T_FREE1).x, 1)
      assert.equal(result[0].get_coord(C.T_FREE1).y, 3)
      assert.equal(result[0].get_coord(C.T_FREE2).x, 2)
      assert.equal(result[0].get_coord(C.T_FREE2).y, 3)
      assert.equal(result[1].get_step().direction, C.LEFT)
      assert.equal(result[1].get_step().index, C.T_BING3)
      assert.equal(result[1].get_coord(C.T_BING3).x, 1)
      assert.equal(result[1].get_coord(C.T_BING3).y, 3)
      assert.equal(result[1].get_coord(C.T_FREE1).x, 2)
      assert.equal(result[1].get_coord(C.T_FREE1).y, 3)
      assert.equal(result[1].get_coord(C.T_FREE2).x, 2)
      assert.equal(result[1].get_coord(C.T_FREE2).y, 4)
    })
  })

  describe('move_up_left_1_1', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 0)
      s.set_coord(C.T_BING1, 1, 2)
      s.set_coord(C.T_BING2, 2, 3)
      s.set_coord(C.T_BING3, 0, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 2, 2)
      s.set_coord(C.T_FREE2, 1, 3)
      let result = s._get1_1next(C.T_BING2)
      assert.equal(result.length, 2)
      assert.equal(result[0].get_step().direction, C.UP)
      assert.equal(result[0].get_step().index, C.T_BING2)
      assert.equal(result[0].get_coord(C.T_BING2).x, 2)
      assert.equal(result[0].get_coord(C.T_BING2).y, 2)
      assert.equal(result[0].get_coord(C.T_FREE1).x, 2)
      assert.equal(result[0].get_coord(C.T_FREE1).y, 3)
      assert.equal(result[0].get_coord(C.T_FREE2).x, 1)
      assert.equal(result[0].get_coord(C.T_FREE2).y, 3)
      assert.equal(result[1].get_step().direction, C.LEFT)
      assert.equal(result[1].get_step().index, C.T_BING2)
      assert.equal(result[1].get_coord(C.T_BING2).x, 1)
      assert.equal(result[1].get_coord(C.T_BING2).y, 3)
      assert.equal(result[1].get_coord(C.T_FREE1).x, 2)
      assert.equal(result[1].get_coord(C.T_FREE1).y, 2)
      assert.equal(result[1].get_coord(C.T_FREE2).x, 2)
      assert.equal(result[1].get_coord(C.T_FREE2).y, 3)
    })
  })

  describe('move_up_2_2', function() {
    it('', function() {
      let s = new State()
      s.set_coord(C.T_CAO, 1, 1)
      s.set_coord(C.T_BING1, 1, 3)
      s.set_coord(C.T_BING2, 2, 3)
      s.set_coord(C.T_BING3, 0, 4)
      s.set_coord(C.T_BING4, 3, 4)
      s.set_coord(C.T_MA, 0, 0)
      s.set_coord(C.T_HUANG, 0, 2)
      s.set_coord(C.T_ZHANG, 3, 0)
      s.set_coord(C.T_ZHAO, 3, 2)
      s.set_coord(C.T_GUAN, 1, 4)
      s.set_coord(C.T_FREE1, 1, 0)
      s.set_coord(C.T_FREE2, 2, 0)
      let result = s._get2_2next(C.T_CAO)
      assert.equal(result.length, 1)
      assert.equal(result[0].get_step().direction, C.UP)
      assert.equal(result[0].get_step().index, C.T_CAO)
      assert.equal(result[0].get_coord(C.T_CAO).x, 1)
      assert.equal(result[0].get_coord(C.T_CAO).y, 0)
      assert.equal(result[0].get_coord(C.T_FREE1).x, 1)
      assert.equal(result[0].get_coord(C.T_FREE1).y, 2)
      assert.equal(result[0].get_coord(C.T_FREE2).x, 2)
      assert.equal(result[0].get_coord(C.T_FREE2).y, 2)
    })
  })

    describe('move_down_2_2', function() {
      it('', function() {
        let s = new State()
        s.set_coord(C.T_CAO, 1, 0)
        s.set_coord(C.T_BING1, 1, 3)
        s.set_coord(C.T_BING2, 2, 3)
        s.set_coord(C.T_BING3, 0, 4)
        s.set_coord(C.T_BING4, 3, 4)
        s.set_coord(C.T_MA, 0, 0)
        s.set_coord(C.T_HUANG, 0, 2)
        s.set_coord(C.T_ZHANG, 3, 0)
        s.set_coord(C.T_ZHAO, 3, 2)
        s.set_coord(C.T_GUAN, 1, 4)
        s.set_coord(C.T_FREE1, 1, 2)
        s.set_coord(C.T_FREE2, 2, 2)
        let result = s._get2_2next(C.T_CAO)
        assert.equal(result.length, 1)
        assert.equal(result[0].get_step().direction, C.DOWN)
        assert.equal(result[0].get_step().index, C.T_CAO)
        assert.equal(result[0].get_coord(C.T_CAO).x, 1)
        assert.equal(result[0].get_coord(C.T_CAO).y, 1)
        assert.equal(result[0].get_coord(C.T_FREE1).x, 1)
        assert.equal(result[0].get_coord(C.T_FREE1).y, 0)
        assert.equal(result[0].get_coord(C.T_FREE2).x, 2)
        assert.equal(result[0].get_coord(C.T_FREE2).y, 0)
      })
    })

    describe('move_right_2_2', function() {
      it('', function() {
        let s = new State()
        s.set_coord(C.T_CAO, 1, 0)
        s.set_coord(C.T_BING1, 1, 2)
        s.set_coord(C.T_BING2, 1, 3)
        s.set_coord(C.T_BING3, 0, 4)
        s.set_coord(C.T_BING4, 3, 4)
        s.set_coord(C.T_MA, 0, 0)
        s.set_coord(C.T_HUANG, 0, 2)
        s.set_coord(C.T_ZHANG, 2, 2)
        s.set_coord(C.T_ZHAO, 3, 2)
        s.set_coord(C.T_GUAN, 1, 4)
        s.set_coord(C.T_FREE1, 3, 0)
        s.set_coord(C.T_FREE2, 3, 1)
        let result = s._get2_2next(C.T_CAO)
        assert.equal(result.length, 1)
        assert.equal(result[0].get_step().direction, C.RIGHT)
        assert.equal(result[0].get_step().index, C.T_CAO)
        assert.equal(result[0].get_coord(C.T_CAO).x, 2)
        assert.equal(result[0].get_coord(C.T_CAO).y, 0)
        assert.equal(result[0].get_coord(C.T_FREE1).x, 1)
        assert.equal(result[0].get_coord(C.T_FREE1).y, 0)
        assert.equal(result[0].get_coord(C.T_FREE2).x, 1)
        assert.equal(result[0].get_coord(C.T_FREE2).y, 1)
      })
    })

    describe('move_left_2_2', function() {
      it('', function() {
        let s = new State()
        s.set_coord(C.T_CAO, 2, 0)
        s.set_coord(C.T_BING1, 1, 2)
        s.set_coord(C.T_BING2, 1, 3)
        s.set_coord(C.T_BING3, 0, 4)
        s.set_coord(C.T_BING4, 3, 4)
        s.set_coord(C.T_MA, 0, 0)
        s.set_coord(C.T_HUANG, 0, 2)
        s.set_coord(C.T_ZHANG, 2, 2)
        s.set_coord(C.T_ZHAO, 3, 2)
        s.set_coord(C.T_GUAN, 1, 4)
        s.set_coord(C.T_FREE1, 1, 0)
        s.set_coord(C.T_FREE2, 1, 1)
        let result = s._get2_2next(C.T_CAO)
        assert.equal(result.length, 1)
        assert.equal(result[0].get_step().direction, C.LEFT)
        assert.equal(result[0].get_step().index, C.T_CAO)
        assert.equal(result[0].get_coord(C.T_CAO).x, 1)
        assert.equal(result[0].get_coord(C.T_CAO).y, 0)
        assert.equal(result[0].get_coord(C.T_FREE1).x, 3)
        assert.equal(result[0].get_coord(C.T_FREE1).y, 0)
        assert.equal(result[0].get_coord(C.T_FREE2).x, 3)
        assert.equal(result[0].get_coord(C.T_FREE2).y, 1)
      })
    })

    describe('key', function() {
      it('', function() {
        let s1 = new State()
        s1.set_coord(C.T_CAO, 2, 0)
        s1.set_coord(C.T_BING1, 1, 2)
        s1.set_coord(C.T_BING2, 1, 3)
        s1.set_coord(C.T_BING3, 0, 4)
        s1.set_coord(C.T_BING4, 3, 4)
        s1.set_coord(C.T_MA, 0, 0)
        s1.set_coord(C.T_HUANG, 0, 2)
        s1.set_coord(C.T_ZHANG, 2, 2)
        s1.set_coord(C.T_ZHAO, 3, 2)
        s1.set_coord(C.T_GUAN, 1, 4)
        s1.set_coord(C.T_FREE1, 1, 0)
        s1.set_coord(C.T_FREE2, 1, 1)
        let s2 = new State()
        s2.set_coord(C.T_CAO, 2, 0)
        s2.set_coord(C.T_BING1, 1, 2)
        s2.set_coord(C.T_BING2, 1, 3)
        s2.set_coord(C.T_BING3, 0, 4)
        s2.set_coord(C.T_BING4, 3, 4)
        s2.set_coord(C.T_MA, 3, 2)
        s2.set_coord(C.T_HUANG, 0, 2)
        s2.set_coord(C.T_ZHANG, 2, 2)
        s2.set_coord(C.T_ZHAO, 0, 0)
        s2.set_coord(C.T_GUAN, 1, 4)
        s2.set_coord(C.T_FREE1, 1, 0)
        s2.set_coord(C.T_FREE2, 1, 1)
        assert.equal(s1.key(), s2.key())
      })
    })
})